dotnet パフォーマンスプロファイラを使ってみた

2024-10-25

VisualStudio

VisualStudioにパフォーマンスプロファイラなるものを見つけたので使い方を 確認してみました

1

学ぶより慣れろということで、取り合えず使い始めてみます

フレームワークのバージョンや種類によって使用できるツールに差異があるようです

触ってみた感想としては、これだけ様々な情報が得られれば、これらのツールで概ねパフォーマンスに関する問題は解決できそうだと感じました

昔は、WinDbgを使ったり、外部ツールで情報収集していましたが、 そういったツールももう必要なく、VisualStudio同梱のパフォーマンスツールで事足りるという印象です

.NET Async

非同期及び待機の使用状況を調べるツール

using System.Net.NetworkInformation;

int failed = 0;
var tasks = new List<Task>();
String[] urls = { "www.adatum.com", "www.cohovineyard.com",
                        "www.cohowinery.com", "www.northwindtraders.com",
                        "www.contoso.com" };

foreach (var value in urls)
{
    var url = value;
    tasks.Add(Task.Run(() => {
        var png = new Ping();
        try
        {
            var reply = png.Send(url);
            if (!(reply.Status == IPStatus.Success))
            {
                Interlocked.Increment(ref failed);
                throw new TimeoutException("Unable to reach " + url + ".");
            }
        }
        catch (PingException)
        {
            Interlocked.Increment(ref failed);
            throw;
        }
    }));
}
Task t = Task.WhenAll(tasks);
try
{
    t.Wait();
}
catch { }

if (t.Status == TaskStatus.RanToCompletion)
    Console.WriteLine("All ping attempts succeeded.");
else if (t.Status == TaskStatus.Faulted)
    Console.WriteLine("{0} ping attempts failed", failed);

await Task.Delay(2000);

タスクの数や実行時間が指定期間内で確認できる
また、タスクを実行した関数にジャンプすることもできる

名前カウント開始時間 (ミリ秒)終了時間 (ミリ秒)合計時間 (ミリ秒)
 + Task.WhenAll12,129.523,361.901,232.38
| + Program.Main.AnonymousMethod__0()52,126.813,361.90589.49(平均)
|| + [詳細]52,126.813,361.90589.49(平均)
||| - 標準分散内に 4 行42,126.813,361.90568.69(平均)
||| - [タスク]Program.Main.AnonymousMethod__0()12,689.203,361.90672.70
 + Program.Main()13,396.675,407.862,011.19
| + Task.Delay13,383.975,409.152,025.18

.NET カウンター

EventCounter API または Meter API を使用して公開されたパフォーマンス カウンターの値を監視できます。

使用しているライブラリによりカウンターが変化します。   パフォーマンス調査の入口で最も使いそうな機能です。

2

3

イベントビューワ

汎用イベント ビューアーには、モジュールの読み込み、スレッドの開始、システムの構成などのイベントの一覧を使用して、アプリのアクティビティが表示されます。

中身はかなりコアな内容が多岐に渡り記録されていました。
今の私には使いこなすのは難しそう。
不具合の手がかりが得られない場合に、イベントビューワから探っていくといった使い方はできるかもしれません。
ログ量が多いので基本的にフィルターして使うものだと思います。 4

データべース

データベース クエリを記録します。 その後、個々のクエリに関する情報を分析して、アプリのパフォーマンスを向上させるための場所を見つけることができます。

スロークエリをログできないようなシンプルなDBの場合には便利だと思います。 ADO.NET または Entity Framework Core を使った場合に測定されます。

開始時刻 (秒)クエリ期間 (ミリ秒)影響を受けたレコード読み取ったレコード
 - 5.817INSERT INTO “Blogs” (“Url”)VALUES (@p0)RETURNING “BlogId”;49.59911
 - 7.059SELECT “b”.”BlogId”, “b”.”Url” FROM “Blogs” AS “b” ORDER BY “b”.”BlogId” LIMIT 13.90502
 + 7.124TransactionCommitted56.61022
| - 7.131UPDATE “Blogs” SET “Url” = @p0 WHERE “BlogId” = @p1 RETURNING 1;5.07611
| - 7.141INSERT INTO “Posts” (“BlogId”, “Content”, “Title”) VALUES (@p0, @p1, @p2) RETURNING “PostId”;4.98111
 + 7.202TransactionCommitted7.49022
| - 7.203DELETE FROM “Posts” WHERE “PostId” = @p0 RETURNING 1;1.36911
| - 7.205DELETE FROM “Blogs” WHERE “BlogId” = @p0 RETURNING 1;0.44411

メモリ使用量

アプリのメモリ使用量を監視します。

コードは個々のものを使用しました。 https://github.com/dotnet/samples/tree/main/core/diagnostics/DiagnosticScenarios

5

スナップショットを取ると、マネージドオブジェクトの数やメモリ使用量が確認できます

6

.NETオブジェクト割り当て追跡

マネージドオブジェクトの割り当てと解放を追跡します

どのオブジェクトがどれ位割り当てられたか確認できます 7

どの関数でどのオブジェクトがどれ位割り当てられたか確認できます 8

どのオブジェクトが何回目のGCでどれ位解放されたか確認できます

9

インストルメンテーション

関数が呼び出された正確な回数や時間が確認できます

どの関数がどれ位時間が掛かっているか確認できます 10

関数の呼び出し回数が確認できます 11

呼び出し履歴も確認できます 12

フレームグラフも確認できます 13

ファイルI/O

ファイルI/Oの読み書き量や回数が確認できます

13